package service

import (
	"context"
	"crypto/aes"
	"crypto/cipher"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"gitee.com/huerbiao/robot/model/tbl_robot"
	"gitee.com/huerbiao/robot/pkg/feishu"
	"gitee.com/huerbiao/robot/pkg/logger"
	"gitee.com/huerbiao/robot/service/structure/request"
	"gitee.com/huerbiao/robot/service/templet"
	"github.com/gin-gonic/gin"
	larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1"
	"net/http"
	"runtime"
	"strings"
)

// 定义签名验证函数
func verifySignature(r *http.Request, encryptKey string) bool {
	signature := r.Header.Get("X-Lark-Signature")
	timestamp := r.Header.Get("X-Lark-Timestamp")
	nonce := r.Header.Get("X-Lark-Nonce")

	// 拼接原始字符串
	original := fmt.Sprintf("%s\n%s\n%s", timestamp, nonce, encryptKey)

	// 计算签名
	hash := hmac.New(sha256.New, []byte(encryptKey))
	hash.Write([]byte(original))
	expectedSignature := base64.StdEncoding.EncodeToString(hash.Sum(nil))

	// 验证签名
	return hmac.Equal([]byte(signature), []byte(expectedSignature))
}

// 定义处理请求的函数
func HandleRobotRequest(msg string) error {
	defer func() {
		if err := recover(); err != nil {
			stackSlice := make([]byte, 4096)
			s := runtime.Stack(stackSlice, false)
			logger.Error(err, string(stackSlice[0:s]))
		}
	}()

	var req request.EventWrapper
	err := json.Unmarshal([]byte(msg), &req)
	fmt.Println("HandleRobotRequest", err)
	if err != nil {
		return err
	}
	// 根据事件类型处理逻辑
	switch req.Header.EventType {
	case "im.message.receive_v1":
		// 处理消息接收事件
		// ...
		// 发送响应消息
		// ...
		logger.Info("im.message.receive_v1", req.Event.Message.MessageID)
		go replyMsg(req.Event.Message.MessageID, req.Event.Message.Content)
		//写入数据
		tblRobot := tbl_robot.TblRobot{
			MessageID:   req.Event.Message.MessageID,
			ChatID:      req.Event.Message.ChatID,
			ChatType:    req.Event.Message.ChatType,
			Content:     req.Event.Message.Content,
			MessageType: req.Event.Message.MessageType,
			//ParentID:      req.Event.Message.ParentID,
			//RootID:        req.Event.Message.RootID,
			//ThreadID:      req.Event.Message.ThreadID,
			//SenderOpenID:  req.Event.Message.SenderOpenID,
			//SenderUnionID: req.Event.Message.SenderUnionID,
			//SenderUserID:  req.Event.Message.SenderUserID,
			//SenderType:    req.Event.Message.SenderType,
			//TenantKey:     req.Event.Message.TenantKey,
		}
		_, err := tbl_robot.AddTblRobot(tblRobot)
		if err != nil {
			return err
		}
	default:
		// 处理其他事件类型
		// ...
	}
	return nil
}

func RobotPostMsg(c *gin.Context) {
	var jsonMap map[string]interface{}

	if err := c.ShouldBindJSON(&jsonMap); err != nil {
		c.AbortWithError(http.StatusBadRequest, err)
		return
	}

	encrypt, exists := jsonMap["encrypt"].(string)
	fmt.Println(encrypt)
	if exists {
		// 解密encrypt字段
		cxt, err := Decrypt(encrypt, "85huQ6wftg5cjhZizEg6vcDxzDjH06WW")
		fmt.Println(cxt)
		if err != nil {
			c.AbortWithError(http.StatusBadRequest, err)
			return
		}

		// 处理请求
		err = HandleRobotRequest(cxt)
		if err == nil {
			// 在1秒内回复CHALLENGE值
			c.String(http.StatusOK, "OK")
			return
		}
		err = json.Unmarshal([]byte(cxt), &jsonMap)
		// 将解密后的JSON数据解析到jsonMap中
		if err != nil {
			c.AbortWithError(http.StatusBadRequest, err)
			return
		}
	}

	// 以下是兼容另一种情况
	// 从JSON数据中提取CHALLENGE参数
	challenge, exists := jsonMap["challenge"].(string)
	if !exists {
		c.AbortWithStatus(http.StatusBadRequest)
		return
	}

	var response = map[string]string{
		"challenge": challenge,
	}

	// 在1秒内回复CHALLENGE值
	c.JSON(http.StatusOK, response)
}

func Decrypt(encrypt string, key string) (string, error) {
	buf, err := base64.StdEncoding.DecodeString(encrypt)
	if err != nil {
		return "", fmt.Errorf("base64StdEncode Error[%v]", err)
	}
	if len(buf) < aes.BlockSize {
		return "", errors.New("cipher  too short")
	}
	keyBs := sha256.Sum256([]byte(key))
	block, err := aes.NewCipher(keyBs[:sha256.Size])
	if err != nil {
		return "", fmt.Errorf("AESNewCipher Error[%v]", err)
	}
	iv := buf[:aes.BlockSize]
	buf = buf[aes.BlockSize:]
	// CBC mode always works in whole blocks.
	if len(buf)%aes.BlockSize != 0 {
		return "", errors.New("ciphertext is not a multiple of the block size")
	}
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(buf, buf)
	n := strings.Index(string(buf), "{")
	if n == -1 {
		n = 0
	}
	m := strings.LastIndex(string(buf), "}")
	if m == -1 {
		m = len(buf) - 1
	}
	return string(buf[n : m+1]), nil
}

func replyMsg(messageId, content string) {
	// 创建 Client
	client := feishu.GetFSClient()

	dialog := &templet.Dialog{
		Content: content,
	}
	replay := map[string]string{
		"text": dialog.Reply(),
	}
	replayContent, _ := json.Marshal(replay)
	// 创建请求对象
	req := larkim.NewReplyMessageReqBuilder().
		MessageId(messageId).
		Body(larkim.NewReplyMessageReqBodyBuilder().
			//Content(`{"text":"test content"}`).
			Content(string(replayContent)).
			MsgType(`text`).
			ReplyInThread(true).
			//Uuid(`选填，若填写每次调用前请更换，如：a0d69e20-1dd1-458b-k525-dfeca4015204`).
			Build()).
		Build()

	// 发起请求
	resp, err := client.Im.Message.Reply(context.Background(), req)
	// 处理错误
	if err != nil {
		logger.Info("client.Im.Message.Reply", err)
		return
	}
	// 服务端错误处理
	if !resp.Success() {
		logger.Info(resp.Code, resp.Msg, resp.RequestId())
		return
	}
	// 打印返回结果
	fmt.Println(resp.Data)
}
